<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Zend_Amf_Server - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/zend.amf.server.html">Inglês (English)</a></li>
    <li><a href="../pt-br/zend.amf.server.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.amf.introduction.html">Introdu&ccedil;&atilde;o</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.amf.html">Zend_Amf</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.application.html">Zend_Application</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="zend.amf.server" class="section"><div class="info"><h1 class="title">Zend_Amf_Server</h1></div>
    

    <p class="para">
        <span class="classname">Zend_Amf_Server</span> fornece um servidor no estilo <acronym class="acronym">RPC</acronym>
        para manipular requisições feitas com Adobe Flash Player usando o protocolo
        <acronym class="acronym">AMF</acronym>. Como todas as classes de servidor do Zend Framework, ela segue a
        <acronym class="acronym">API</acronym> SoapServer, fornecendo uma interface fácil de lembrar para criar
        servidores.
    </p>

    <div class="example" id="zend.amf.server.basic"><div class="info"><p><b>Example #1 Servidor AMF Básico</b></p></div>
        
        <div class="example-contents"><p>
            Vamos assumir que você tenha criado uma classe <span class="classname">Foo</span> com uma
            variedade de métodos públicos. Você pode criar um servidor <acronym class="acronym">AMF</acronym> usando
            o código a seguir:
        </p></div>

        <pre class="programlisting brush: php">
$server = new Zend_Amf_Server();
$server-&gt;setClass(&#039;Foo&#039;);
$response = $server-&gt;handle();
echo $response;
</pre>


        <div class="example-contents"><p>
            Alternativamente, você pode optar por atribuir uma simples função como chamada de
            retorno:
        </p></div>

        <pre class="programlisting brush: php">
$server = new Zend_Amf_Server();
$server-&gt;addFunction(&#039;myUberCoolFunction&#039;);
$response = $server-&gt;handle();
echo $response;
</pre>


        <div class="example-contents"><p>
            Você também pode misturar e combinar várias classes e funções. Quando fizer isso,
            sugerimos que utilize namespaces para que nenhuma colisão de nomes de métodos ocorra;
            isso pode ser feito simplesmente passando uma string como segundo argumento, tanto para
             <span class="methodname">addFunction()</span> ou  <span class="methodname">setClass()</span>.
        </p></div>

        <pre class="programlisting brush: php">
$server = new Zend_Amf_Server();
$server-&gt;addFunction(&#039;myUberCoolFunction&#039;, &#039;my&#039;)
       -&gt;setClass(&#039;Foo&#039;, &#039;foo&#039;)
       -&gt;setClass(&#039;Bar&#039;, &#039;bar&#039;);
$response = $server-&gt;handle();
echo $response;
</pre>


        <div class="example-contents"><p>
            O <span class="classname">Zend_Amf_Server</span> também permite que serviços sejam
            dinamicamente carregados baseado em um caminho de diretório fornecido. Você pode
            adicionar tantos quantos diretórios desejar ao servidor. A ordem em que você adiciona os
            diretórios ao servidor será a ordem em que a pesquisa <acronym class="acronym">LIFO</acronym> será
            realizada nos diretórios para encontrar a classe. Adição de diretórios é feita com
            o método  <span class="methodname">addDirectory()</span>.
        </p></div>

        <pre class="programlisting brush: php">
$server-&gt;addDirectory(dirname(__FILE__) .&#039;/../services/&#039;);
$server-&gt;addDirectory(dirname(__FILE__) .&#039;/../package/&#039;);
</pre>


        <div class="example-contents"><p>
            Ao chamar serviços remotos, os nomes de seus fontes podem conter sublinhados (&quot;_&quot;) e
            pontos (&quot;.&quot;) como delimitadores de diretórios. Quando um sublinhado é usado, as
            conveções <acronym class="acronym">PEAR</acronym> e Zend Framework para nomenclaturas serão respeitadas.
            Isso significa que se você chamar um serviço <var class="filename">com_Foo_Bar</var> o servidor
            procurará pelo arquivo <var class="filename">Bar.php</var> em cada caminho incluído em
            <var class="filename">com/Foo/Bar.php</var>. Se a notação de ponto é usada para seu serviço
            remoto como em <var class="filename">com.Foo.Bar</var>, <var class="filename">com/Foo/Bar.php</var>
            será adicionado ao final de cada caminho incluído para autocarregar
            <var class="filename">Bar.php</var>
        </p></div>

        <div class="example-contents"><p>
            Todas as requisições <acronym class="acronym">AMF</acronym> enviadas ao script serão manipuladas
            posteriormente pelo servidor, e uma resposta <acronym class="acronym">AMF</acronym> será retornada.
        </p></div>
    </div>

    <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>
            Todas as Funções e Métodos atribuídos precisam de Blocos de Documentação (Docblocks)
        </b><br /></span>
        

        <p class="para">
            Como todos os componentes de servidor no Zend Framework, você precisa documentar seus
            métodos de classe usando docblocks <acronym class="acronym">PHP</acronym>. Você precisa fornecer,
            no mínimo, anotações para cada argumento obrigatório assim como o valor de retorno.
            Exemplo:
        </p>

        <pre class="programlisting brush: php">
// Função para atribuição:

/**
 * @param  string $name
 * @param  string $greeting
 * @return string
 */
function helloWorld($name, $greeting = &#039;Hello&#039;)
{
    return $greeting . &#039;, &#039; . $name;
}
</pre>


        <pre class="programlisting brush: php">
// Classe atribuída

class World
{
    /**
     * @param  string $name
     * @param  string $greeting
     * @return string
     */
    public function hello($name, $greeting = &#039;Hello&#039;)
    {
        return $greeting . &#039;, &#039; . $name;
    }
}
</pre>


        <p class="para">
            Outras anotações podem ser usadas, mas serão ignoradas.
        </p>
    </p></blockquote>

    <div class="section" id="zend.amf.server.flex"><div class="info"><h1 class="title">Conectando ao servidor com Flex</h1></div>
        

        <p class="para">
            Conectar a seu <span class="classname">Zend_Amf_Server</span> a partir de seu projeto Flex é
            bem simples; você simplesmente precisa apontar sua <acronym class="acronym">URI</acronym> de ponto de
            extremidade (endpoint) para seu script <span class="classname">Zend_Amf_Server</span>
        </p>

        <p class="para">
            Digamos, por exemplo, que você tenha criado seu servidor e o colocado no arquivo
            <var class="filename">server.php</var> na raiz de sua aplicação, e seu <acronym class="acronym">URI</acronym> é
            <var class="filename">http://example.com/server.php</var>. Neste caso, você modificaria seu
            arquivo <var class="filename">services-config.xml</var> para definir o atributo uri de ponto de
            extremidade, <span class="property">channel</span>, para este valor.
        </p>

        <p class="para">
            Se você nunca criou um arquivo <var class="filename">services-config.xml</var> você poderá
            fazê-lo abrindo seu projeto na janela &#039;Navigator&#039; do Flex Builder. Clique com o botão
            direito sobre nome do projeto e selecione &#039;properties&#039;. Na janela de diálogo de
            propriedades do projeto vá para o menu &#039;Flex Build Path&#039;, aba &#039;Library path&#039; e tenha
            certeza de que o arquivo &#039;<var class="filename">rpc.swc</var>&#039; foi adicionado aos caminhos de
            seus projetos e pressione &#039;Ok&#039; para fechar a janela.
        </p>

        <p class="para">
            Você também precisará informar ao compilador para usar o arquivo
            <var class="filename">services-config.xml</var> para encontrar o ponto de extremidade do
            <span class="classname">RemoteObject</span>. Para isso, abra novamente o painel de propriedades
            de seu projeto clicando com o botão direito do mouse no diretório do projeto a partir
            da janela &#039;Navigator&#039; e selecionando &#039;properties&#039;. Na popup de propriedades selecione
            &#039;Flex COmpiler&#039; e adicione a seqüência de caracteres:
            <strong class="command">-services &quot;services-config.xml&quot;</strong>. Pressione &#039;Apply&#039; e depois &#039;OK&#039; para
            voltar e atualizar a opção. O que você acabou de fazer foi dizer ao compilador Flex para
            procurar por variáveis de tempo de execução no arquivo
            <var class="filename">services-config.xml</var> que serão usadas pela classe
            <span class="classname">RemoteObject</span>
        </p>

        <p class="para">
            Agora precisamos dizer ao Flex qual arquivo de configuração de serviços usar para
            conectar a nossos métodos remotos. Por essa razão crie um novo arquivo
            &#039;<var class="filename">services-config.xml</var>&#039; em seu diretório <var class="filename">src</var> do
            seu projeto Flex. Pra fazer isso clique com o botão direito no diretório do projeto e
            selecione &#039;new&#039;; &#039;File&#039; que uma nova janela se abrirá. Selecione o diretório do projeto
            e nomeie o arquivo &#039;<var class="filename">services-config.xml</var>&#039; e pressione &#039;finish&#039;.
        </p>

        <p class="para">
            O Flex criou um novo <var class="filename">servies-config.xml</var> e o abriu. Use o texto de
            exemplo a seguir para seu arquivo <var class="filename">services-config.xml</var>. Tenha
            certeza de atualizar seu ponto de extremidade (endpoint) para coincidir com seu servidor
            de testes e que você salve o arquivo.
        </p>

        <pre class="programlisting brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;services-config&gt;
    &lt;services&gt;
        &lt;service id=&quot;zend-service&quot;
            class=&quot;flex.messaging.services.RemotingService&quot;
            messageTypes=&quot;flex.messaging.messages.RemotingMessage&quot;&gt;
            &lt;destination id=&quot;zend&quot;&gt;
                &lt;channels&gt;
                    &lt;channel ref=&quot;zend-endpoint&quot;/&gt;
                &lt;/channels&gt;
                &lt;properties&gt;
                    &lt;source&gt;*&lt;/source&gt;
                &lt;/properties&gt;
            &lt;/destination&gt;
        &lt;/service&gt;
    &lt;/services&gt;
    &lt;channels&gt;
        &lt;channel-definition id=&quot;zend-endpoint&quot;
            class=&quot;mx.messaging.channels.AMFChannel&quot;&gt;
            &lt;endpoint uri=&quot;http://example.com/server.php&quot;
                class=&quot;flex.messaging.endpoints.AMFEndpoint&quot;/&gt;
        &lt;/channel-definition&gt;
    &lt;/channels&gt;
&lt;/services-config&gt;
</pre>


        <p class="para">
            Há dois pontos chave no exemplo. Primeiro, mas por último na listagem, criamos um canal
            <acronym class="acronym">AMF</acronym> e especificados o poonto de extremidade (endpoint) como
            <acronym class="acronym">URL</acronym> para nosso <span class="classname">Zend_Amf_Server</span>:
        </p>

        <pre class="programlisting brush: xml">
&lt;channel-definition id=&quot;zend-endpoint&quot;
    &lt;endpoint uri=&quot;http://example.com/server.php&quot;
        class=&quot;flex.messaging.endpoints.AMFEndpoint&quot;/&gt;
&lt;/channel-definition&gt;
</pre>


        <p class="para">
            Note que demos a este canal um identificador, &quot;zend-endpoint&quot;. O exemplo cria um destino
            de serviço que se refere a este canal, atribuindo a ele um ID também - neste caso
            &quot;zend&quot;.
        </p>

        <p class="para">
            Em nossos arquivos <acronym class="acronym">MXML</acronym> do Flex, precisamos ligar um
            <span class="classname">RemoteObject</span> ao serviço. Em <acronym class="acronym">MXML</acronym>, isto é feito
            como a seguir:
        </p>

        <pre class="programlisting brush: xml">
&lt;mx:RemoteObject id=&quot;myservice&quot;
    fault=&quot;faultHandler(event)&quot;
    showBusyCursor=&quot;true&quot;
    destination=&quot;zend&quot;&gt;
</pre>


        <p class="para">
            Aqui, definimos um novo objeto remoto identificado por &quot;myservice&quot; ligado ao destino de
            serviço &quot;zend&quot; que definimos no arquivo <var class="filename">services-config.xml</var>. Nós
            depois chamamos métodos em nosso ActionScript simplesmente
            chamando &quot;myservice.&lt;método&gt;&quot;. Como no exemplo:
        </p>

        <pre class="programlisting brush: ActionScript">
myservice.hello(&quot;Wade&quot;);
</pre>


        <p class="para">
            Quando usando espaços de nomes (namespaces), usamos:
            &quot;myservice.&lt;espaço de nome&gt;.&lt;método&gt;&quot;:
        </p>

        <pre class="programlisting brush: ActionScript">
myservice.world.hello(&quot;Wade&quot;);
</pre>


        <p class="para">
            Para mais informações sobre como utilizar o <span class="classname">RemoteObject</span> do Flex,
            <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html" class="link external">&raquo; 
            visite o site da Ajuda do Adobre Flex 3</a>.
        </p>
    </div>

    <div class="section" id="zend.amf.server.errors"><div class="info"><h1 class="title">Manipulação de Erros</h1></div>
        

        <p class="para">
            Por padrão, todas as exceções lançadas em suas classes ou funções anexadas serão obtidas
            e retornadas como <span class="classname">ErrorMessage</span>s do <acronym class="acronym">AMF</acronym>.
            No entando, o conteúdos destes objetos <span class="classname">ErrorMessage</span> variam se
            o servidor está ou não em modo de &quot;produção&quot; (o estado padrão).
        </p>

        <p class="para">
            Quando em modo de produção, somente o código da exceção será retornado. Se você
            desabilitar o modo de produção - algo que você deve fazer apenas para testes - a maioria
            dos detalhes de exceção serão retornados: a mensagem de exceção, linha, e
            pilha de execução (backtrace) serão todos anexados.
        </p>

        <p class="para">
            Para desabilitar o modo de produção, faça o seguinte:
        </p>

        <pre class="programlisting brush: php">
$server-&gt;setProduction(false);
</pre>


        <p class="para">
            Para habilitá-lo novamnete, passe um valor booleano <b><tt>TRUE</tt></b>:
        </p>

        <pre class="programlisting brush: php">
$server-&gt;setProduction(true);
</pre>


        <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>Desabilite o modo de produção com moderação!</b><br /></span>
            

            <p class="para">
                Recomendamos desabilitar o modo de produção somente durante o desenvolvimento.
                Mensagens de exceção e pilhas de execução podem conter informações sensíveis que
                você provavelmente não deseje que terceiros tenham acesso. Mesmo
                <acronym class="acronym">AMF</acronym> sendo um formato binário, a especificação é aberta, o que
                quer dizer que qualquer um pode, potencialmente, desserializar os dados carregados.
            </p>
        </p></blockquote>

        <p class="para">
            Uma área para ser especialmente cuidadoso são os próprios erros <acronym class="acronym">PHP</acronym>.
            Quando a diretiva <span class="property">display_errors</span> do <acronym class="acronym">INI</acronym> está
            habilitada, qualquer erro <acronym class="acronym">PHP</acronym> para o nível atual de reltório de erros
            são mostrados diretamente na saída - potencialmente interrompendo a carga de dados
            <acronym class="acronym">AMF</acronym>. Sugerimos desabilitar a diretiva
            <span class="property">display_errors</span> em modo de produção para evitar tais problemas
        </p>
    </div>

    <div class="section" id="zend.amf.server.response"><div class="info"><h1 class="title">Respostas AMF</h1></div>
        

        <p class="para">
            Ocasionalmente você pode desejar manipular levemente o objeto de resposta, tipicamente
            para retornar cabeçalhos de mensagem extra. O método  <span class="methodname">handle()</span>
            do servidor retorna o objeto da resposta, possibilitando a você fazer isto.
        </p>

        <div class="example" id="zend.amf.server.response.messageHeaderExample"><div class="info"><p><b>Example #2 Adicionando Cabeçalhos de Mensagem à Resposta AMF</b></p></div>
            

            <div class="example-contents"><p>
                Neste exemplo, adicionamos um <span class="classname">MessageHeader</span> &#039;foo&#039; com o
                valor &#039;bar&#039; à resposta antes de retorná-la.
            </p></div>

            <pre class="programlisting brush: php">
$response = $server-&gt;handle();
$response-&gt;addAmfHeader(new Zend_Amf_Value_MessageHeader(&#039;foo&#039;, true, &#039;bar&#039;))
echo $response;
</pre>

        </div>
    </div>

    <div class="section" id="zend.amf.server.typedobjects"><div class="info"><h1 class="title">Objetos Tipados</h1></div>
        

        <p class="para">
            De modo similar ao <acronym class="acronym">SOAP</acronym>, <acronym class="acronym">AMF</acronym> permite que sejam
            passados objetos entre o cliente e o servidor. Isso permite uma grande quantidade de
            flexibilidade e coerência entre os dois ambientes.
        </p>

        <p class="para">
            <span class="classname">Zend_Amf</span> fornece três métodos para mapeamento entre objetos
            ActionScript e <acronym class="acronym">PHP</acronym>.
        </p>

        <ul class="itemizedlist">
            <li class="listitem">
                <p class="para">
                    Primeiro, você deve criar explicitamente ligações no nível do servidor, usando o
                    método  <span class="methodname">setClassMap()</span>. O primeiro argumento é o nome da
                    classe ActionScript, o segundo é a classe <acronym class="acronym">PHP</acronym> que a mapeia:
                </p>

                <pre class="programlisting brush: php">
// Mapeia a classe ActionScript &#039;ContactVO&#039; para a classe PHP &#039;Contact&#039;:
$server-&gt;setClassMap(&#039;ContactVO&#039;, &#039;Contact&#039;);
</pre>

            </li>

            <li class="listitem">
                <p class="para">
                    Em segundo lugar, você definir a propriedade pública
                    <var class="varname">$_explicitType</var> em sua classe <acronym class="acronym">PHP</acronym>, com o
                    valor representando a classe ActionScript para mapear:
                </p>

                <pre class="programlisting brush: php">
class Contact
{
    public $_explicitType = &#039;ContactVO&#039;;
}
</pre>

            </li>

            <li class="listitem">
                <p class="para">
                    Terceiro, de maneira similar, você pode definir o método público
                     <span class="methodname">getASClassName()</span> em sua classe <acronym class="acronym">PHP</acronym>;
                    este método deve retornar a classe ActionScript apropriada:
                </p>

                <pre class="programlisting brush: php">
class Contact
{
    public function getASClassName()
    {
        return &#039;ContactVO&#039;;
    }
}
</pre>

            </li>
        </ul>

        <p class="para">
            Embora tenhamos criado o ContactVO no servidor precisamos agora fazer a classe
            correspondente em <acronym class="acronym">AS3</acronym> para que o objeto de servidor seja mapeado.
        </p>

        <p class="para">
            Clique com o botão direito na pasta <var class="filename">src</var> de seu projeto Flex e
            selecione &#039;New&#039; -&gt; &#039;ActionScript File&#039;. Nomeie o arquivo como &#039;ContactVO&#039; e pressione
            &#039;finish&#039; para ver o novo arquivo. Copie o seguinte código para finalizar a criação da
            classe.
        </p>

        <pre class="programlisting brush: as">
package
{
    [Bindable]
    [RemoteClass(alias=&quot;ContactVO&quot;)]
    public class ContactVO
    {
        public var id:int;
        public var firstname:String;
        public var lastname:String;
        public var email:String;
        public var mobile:String;
        public function ContactVO():void {
        }
    }
}
</pre>


        <p class="para">
            A classe é sintaticamente equivalente à classe <acronym class="acronym">PHP</acronym> com o mesmo nome.
            Os nomes de variáveis são exatamente os mesmos e precisam estar sob o mesmo caso para
            que funcione apropriadamente. Existem duas marcações meta (meta tags)
            <acronym class="acronym">AS3</acronym> únicas nesta classe. A primeira é Bindable, que faz com
            que um evento de alteração (change) seja disparado quando ela é atualizada. A segunda
            marcação é RemoteClass, que define que esta classe pode ter um objeto remoto mapeado a
            ela com um apelido, neste caso <em class="emphasis">ContactVO</em>. É obrigatório que o valor
            desta marcação seja definido seja estritamente equivalente ao da classe
            <acronym class="acronym">PHP</acronym>.
        </p>

        <pre class="programlisting brush: as">
[Bindable]
private var myContact:ContactVO;

private function getContactHandler(event:ResultEvent):void {
    myContact = ContactVO(event.result);
}
</pre>


        <p class="para">
            O evento de resultado gerado pela chamada ao serviço é instantaneamente convertido para
            o ContactVO do Flex. Qualquer coisa que seja direcionada a <var class="varname">myContact</var>
            será atualizado e os dados de ContactVO serão retornados.
        </p>
    </div>

    <div class="section" id="zend.amf.server.resources"><div class="info"><h1 class="title">Recursos</h1></div>
        

        <p class="para">
            <span class="classname">Zend_Amf</span> fornece ferramentas para mapear tipos de recursos
            retornados por classes de serviços em informações consumíveis pelo ActionScript.
        </p>

        <p class="para">
            A fim de lidar com tipo de recurso específico, o usuário precisa criar uma classe plugin
            chamado após o nome do recurso, com palavras em maiúsculas e espaços removidos (assim
            recurso do tipo &quot;resultado mysql&quot; torna-se ResultadoMysql), com algum prefixo, ex.:
            <span class="classname">Meu_ResultadoMysql</span>. Esta classe precisa implementar um método,
             <span class="methodname">parse()</span>, recebendo um argumento - o recurso - e retornando o
            valor a ser enviado para o ActionScript. A classe deve estar localizada no arquivo
            chamado após o nome do componente, ex.: <var class="filename">ResultadoMysql.php</var>.
        </p>

        <p class="para">
            O diretório contendo os plugins para manipulação de recursos devem ser registrados com o
            carregador de tipo <span class="classname">Zend_Amf</span>:
        </p>

        <pre class="programlisting brush: php">
Zend_Amf_Parse_TypeLoader::addResourceDirectory(
    &quot;Meu&quot;,
    &quot;application/library/recursos/Meu&quot;
);
</pre>


        <p class="para">
            Para uma discussão detalhada sobre o plugins carregadores, por favor veja a seção
            <a href="zend.loader.pluginloader.html" class="link">plugin carregador</a>.
        </p>

        <p class="para">
            O diretório padrão para recursos <span class="classname">Zend_Amf</span> é registrado
            automaticamente e atualmente contém manipuladores para recursos &quot;resultado mysql&quot; e
            &quot;stream&quot;.
        </p>

        <pre class="programlisting brush: php">
// Classe de exemplo implementando a manipulação de recursos do tipo &quot;resultado mysql&quot;
class Zend_Amf_Parse_Recurso_ResultadoMysql
{
    /**
     * Decodifica o recurso em uma matriz
     *
     * @param resource $resource
     * @return array
     */
    public function parse($resource) {
        $result = array();
        while($row = mysql_fetch_assoc($resource)) {
            $result[] = $row;
        }
        return $result;
    }
}
</pre>


        <p class="para">
            Ao tentar retornar um tipo desconhecido de recirso (ex., um para o qual não haja plugin
            manipulador existente) resultará em uma exceção.
        </p>
    </div>

    <div class="section" id="zend.amf.server.flash"><div class="info"><h1 class="title">Conectando ao Servidor a partir do Flash</h1></div>
        

        <p class="para">
            Conectando ao seu <span class="classname">Zend_Amf_Server</span> a partir de seu projeto Flash é
            ligeiramente diferente do que com Flex. Contudo, depois da conexão, Flash funciona com
            <span class="classname">Zend_Amf_Server</span> da mesma forma que com Flex. O exemplo a seguir
            também pode ser usado com um arquivo <acronym class="acronym">AS3</acronym> do Flex. Reutilizaremos a
            mesma configuração <span class="classname">Zend_Amf_Server</span> com a classe Mundo para nossa
            conexão.
        </p>

        <p class="para">
            Abra o Flash CS e crie um novo arquivo Flash (ActionScript 3). Nomeie o documento
            <var class="filename">ExemploZend.fla</var> e salve o documento em uma pasta que você usará
            para este exemplo. Crie uma nova classe <acronym class="acronym">AS3</acronym> no mesmo diretório e
            nomeie o arquivo como <var class="filename">Principal.as</var>. Tenha ambos os arquivos abertos
            em seu editor. Vamos conectar os dois arquivos através da classe de documento. Selecione
            ExemploZend e clique no palco. No painel de propriedade dos palco, altere a classe de
            documento (Document class) para Principal. Isso ligará o arquivo ActionScript
            <var class="filename">Principal.as</var> com a interface do usuário do arquivo
            <var class="filename">ExemploZend.fla</var>. Quando você executa o arquivo Flash ExemploZend, a
            classe <var class="filename">Principal.as</var> será executada agora. Agora, vamos adicionar o
            código ActionScript para fazer a chamada <acronym class="acronym">AMF</acronym>.
        </p>

        <p class="para">
            Agora nós faremos a classe Principal de modo que possamos enviar dados ao servidor e
            exibir o resultado. Copie o código a seguir para seu arquivo
            <var class="filename">Principal.as</var> e depois vamos descrever, passo a passo, o papel de
            cada elemento nele.
        </p>

        <pre class="programlisting brush: as">
package {
  import flash.display.MovieClip;
  import flash.events.*;
  import flash.net.NetConnection;
  import flash.net.Responder;

  public class Principal extends MovieClip {
    private var gateway:String = &quot;http://exemplo.com/server.php&quot;;
    private var connection:NetConnection;
    private var responder:Responder;

    public function Principal() {
      responder = new Responder(onResult, onFault);
      connection = new NetConnection;
      connection.addEventListener(NetStatusEvent.NET_STATUS, onComplete);
      connection.connect(gateway);
    }

    public function onComplete( e:NetStatusEvent ):void {
      if(e.info.code == &quot;NetGroup.Connect.Succcess&quot;) {
        var params = &quot;Sent to Server&quot;;
        connection.call(&quot;Mundo.alo&quot;, responder, params);
      }
    }

    private function onResult(result:Object):void {
      // Display the returned data
      trace(String(result));
    }
    private function onFault(fault:Object):void {
      trace(String(fault.description));
    }
  }
}
</pre>


        <p class="para">
            Primeiro precisamos importar duas bibliotecas ActionScriot que executam a maior parte do
            trabalho. A primeira é NetConnection que atua como um tubo bi-direcional entre o cliente
            e o servidor. A segunda é o objeto Responder, que manipula os valores de retorno do
            servidor relacionados ao sucesso ou falha da chamada.
        </p>

        <pre class="programlisting brush: as">
import flash.net.NetConnection;
import flash.net.Responder;
</pre>


        <p class="para">
            Na classe, precisamos de três variáveis para representar a NetConnection, Responder e a
            <acronym class="acronym">URL</acronym> da porta de entrada (gateway) para nossa instalação
            <span class="classname">Zend_Amf_Server</span>.
        </p>

        <pre class="programlisting brush: as">
private var gateway:String = &quot;http://exemplo.com/server.php&quot;;
private var connection:NetConnection;
private var responder:Responder;
</pre>


        <p class="para">
            No contrutor de Principal criamos um respondedor e uma nova conexão ao
            ponto de extremidade (gateway) <span class="classname">Zend_Amf_Server</span>. O respondedor
            define dois métodos diferentes para manipular as respostas do servidor. Por simplicidade
            eles foram chamados de onResult e onFault.
        </p>

        <pre class="programlisting brush: as">
responder = new Responder(onResult, onFault);
connection = new NetConnection;
connection.addEventListener(NetStatusEvent.NET_STATUS, onComplete);
connection.connect(gateway);
</pre>


        <p class="para">
            Na função onComplete, que é executada assim que o construtor tenha sido terminado, nós
            enviamos dados ao servidor. Precisamos adicionar mais uma linha que realiza a chamada a
            função Mundo-&gt;alo do <span class="classname">Zend_Amf_Server</span>
        </p>

        <pre class="programlisting brush: as">
connection.call(&quot;Mundo.alo&quot;, responder, params);
</pre>


        <p class="para">
            Quando instanciamos a variável responder, definimos uma função onResult e onFault para
            manipular a resposta do servidor. Adicionamos esta função para um resultado de sucesso
            vindo do servidor. Um manipulador de eventos de sucesso é executado sempre que uma
            conexão  é manipulada apropriadamente no servidor.
        </p>

        <pre class="programlisting brush: as">
private function onResult(result:Object):void {
    // Mostra os dados retornados
    trace(String(result));
}
</pre>


        <p class="para">
            A função onFault é chamada se há uma resposta inválida vinda do servidor. Isso acontece
            quando há um erro no servidor, a <acronym class="acronym">URL</acronym> para o servidor é inválida, o
            serviço remoto ou método não existe ou se há qualquer outro problema relacionado à
            conexão.
        </p>

        <pre class="programlisting brush: as">
private function onFault(fault:Object):void {
    trace(String(fault.description));
}
</pre>


        <p class="para">
            Completamos então a inclusão do ActionScript para realizar a conexão remota. Executando
            o arquivo ExemploZend agora faz a conexão ao <span class="classname">Zend_Amf</span>. Numa
            revisão, você adicionou as variáveis necessárias para abrir uma conexão ao servidor
            remoto, definiu quais métodos devem ser usados em sua aplicação para receber respostas
            do servidor e finalmente exibido os dados retornados através da função
             <span class="methodname">trace()</span>.
        </p>
    </div>

    <div class="section" id="zend.amf.server.auth"><div class="info"><h1 class="title">Autenticação</h1></div>
        

        <p class="para">
            <span class="classname">Zend_Amf_Server</span> permite que você especifique ganchos de
            autentcação e autorização para controlar acesso aos serviços. Isso é feito usando a
            infraestrutura fornecida pelos componentes
            <a href="zend.auth.html" class="link"><span class="classname">Zend_Auth</span></a> e
            <a href="zend.acl.html" class="link"><span class="classname">Zend_Acl</span></a>.
        </p>

        <p class="para">
            Para definir autenticação, o usuário fornece um adaptador de autenticação extendendo a
            classe abstrata <span class="classname">Zend_Amf_Auth_Abstract</span>. O adaptador deve
            implementar o método  <span class="methodname">authenticate()</span> como qualquer outro
            <a href="zend.auth.introduction.html#zend.auth.introduction.adapters" class="link">adaptador de autenticação</a>.
        </p>

        <p class="para">
            O adaptador deve utilizar as propriedades <em class="emphasis">_username</em> e
            <em class="emphasis">_password</em> da classe pai,
            <span class="classname">Zend_Amf_Auth_Adapter</span>, para autenticar. Estes valores são
            definidos pelo servidor usando o método  <span class="methodname">setCredentials()</span> antes
            da chamada à  <span class="methodname">authenticate()</span> se as credenciais forem recebidas
            nos cabeçalhos da requisição <acronym class="acronym">AMF</acronym>.
        </p>

        <p class="para">
            A identidade retornada pelo adaptador deve ser um objeto contendo a propriedade
            <span class="property">role</span> para que o controle de acesso da <acronym class="acronym">ACL</acronym>
            funcione.
        </p>

        <p class="para">
            Se o resultado da autenticação não for bem sucedido, a requisição não é mais procesada e
            uma mensagem de falha é retornada contendo as razões da falha obtida do resultado.
        </p>

        <p class="para">
            O adaptador é conectado ao servidor usando o método  <span class="methodname">setAuth()</span>:
        </p>

        <pre class="programlisting brush: php">
$server-&gt;setAuth(new My_Amf_Auth());
</pre>


        <p class="para">
            O controle de acesso é realizado usando um objeto <span class="classname">Zend_Acl</span>
            definido pelo método  <span class="methodname">setAcl()</span>:
        </p>

        <pre class="programlisting brush: php">
$acl = new Zend_Acl();
criarPermissoes($acl); // Cria a estrutura de permissões
$server-&gt;setAcl($acl);
</pre>


        <p class="para">
            Se o objeto <acronym class="acronym">ACL</acronym> é definido e a classe sendo chamada define o método
             <span class="methodname">initAcl()</span>, este método será chamado com o objeto
            <acronym class="acronym">ACL</acronym> como um argumento. A classe depois cria regras
            <acronym class="acronym">ACL</acronym> adicionais e retorna <b><tt>TRUE</tt></b>, ou retorna
            <b><tt>FALSE</tt></b> se nenhum controle de acesso for necessário para esta classe.
        </p>

        <p class="para">
            Depois de a <acronym class="acronym">ACL</acronym> ser definida, o servidor verificará se o acesso é
            permitido com o papel definido pela autenticação, sendo o recurso o nome da classe (ou
            <b><tt>NULL</tt></b> para chamadas de funções) e o privileǵio sendo o nome da
            função. Se nenhuma autenticação for fornecida, e se o papel
            <em class="emphasis">anonymous</em> foi definido, ele será usado, em outro caso o acesso será
            negado.
        </p>

        <pre class="programlisting brush: php">
if($this-&gt;_acl-&gt;isAllowed($role, $class, $function)) {
    return true;
} else {
    require_once &#039;Zend/Amf/Server/Exception.php&#039;;
    throw new Zend_Amf_Server_Exception(&quot;Accesso não permitido&quot;);
}
</pre>

    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.amf.introduction.html">Introdu&ccedil;&atilde;o</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.amf.html">Zend_Amf</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.application.html">Zend_Application</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="reference.html">Refer&ecirc;ncia do Zend Framework</a></li>
  <li class="header up"><a href="zend.amf.html">Zend_Amf</a></li>
  <li><a href="zend.amf.introduction.html">Introdu&ccedil;&atilde;o</a></li>
  <li class="active"><a href="zend.amf.server.html">Zend_Amf_Server</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>